Thread: Raising a matrix to a power using arrays and member function operator ^

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    15

    Raising a matrix to a power using arrays and member function operator ^

    As the topic says, I need to write a program that raises a matrix to a user selected power. And do it by using a class Matrix and defining a function operator (^). Here's what I have so far to start with:

    Code:
    #include <iostream> 
    #include <fstream> 
    #include <iomanip>
    #include <string>
    using namespace std;
     
    int main() 
    { 
      Matrix m;
      int n;
      string filename;
     
      :
     
      ifstream InputFile (filename.c_str(), ios::in);
      InputFile >> m;
      InputFile.close();
     
      :
     
      cout << "Matrix "    << endl << m     << endl;
      cout << "Matrix ^ n" << endl << (m^n) << endl;
     
      return 0;
    }
    The semicolons mark where I should ask for and receive the file to read the matrix from, and then ask and receive the integer to raise the matrix to.

    So now I've got to define the class Matrix and the operator...I think that's it. Appreciate any help you can give.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Start with an empty class called Matrix. Then write the shell of the overloaded operator ^ that does nothing. Then compile your code and make sure it is correct so far.

    Then slowly add the code to store the matrix in the Matrix class and compile. Add the code to write out the matrix with operator<<, compile. Add code to read in with operator>>, compile. If you can, test each addition along the way with test code that you can remove later. Eventually you will have a fully functional Matrix class and the assignment will be done.

    If you have specific problems along the way, feel free to post them here.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    15
    Here's something I can modify and use:

    Code:
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string>
    using namespace std;
    
    const int MAX_ROWS = 6;
    const int MAX_COLS = 6;
    
    class Matrix { // Represents a varying-size matrix that
                   // can be input from a file
    public:
      Matrix() {}
      Matrix( int, int, int ); // Constructor that initializes matrix
                               // size and sets all valid elements to
                               // given initial value
      Matrix& operator*=( const Matrix& );
    private:
      int rows;
      int cols;
      int mat[MAX_ROWS][MAX_COLS];
    friend ostream& operator<< ( ostream&, const Matrix& );
    friend istream& operator>> ( istream&, Matrix& );
    };
    
    int main()
    {
    	Matrix m1;
    	Matrix m2;
    	string file1Name;
    	string file2Name;
    
    	cout << "Name of the file containing first matrix => ";
    	cin >> file1Name;
    	ifstream infilOne( file1Name.c_str(), ios::in);
    	infilOne >> m1;
    	infilOne.close();
    
    	cout << "Name of the file containing second matrix => ";
    	cin >> file2Name;
    	ifstream infilTwo(file2Name.c_str(), ios::in);
    	infilTwo >> m2;
    	infilTwo.close();
    
    	if(!infilOne.fail() && ! infilTwo.fail()){
    		cout << endl << "Matrix 1" << endl << endl << m1 << endl << endl;
    		cout << "Matrix 2" << endl << endl << m2 << endl << endl;
    		m1 *= m2;
    		cout << "Matrix 1 x Matrix 2 = " << endl << endl << m1 << endl << endl;
    	}else {
    		cout << "Error in input" << endl;
    	}
    	return 0;
    }
    
    //
    // Constructor that initializes a Matrix object of size initRows
    // x initCols, setting matrix elements to initValue
    //
    Matrix :: Matrix( int initRows, int initCols, int initValue )
    {
      rows = initRows;
      cols = initCols;
      for (int i = 0; i < rows; ++i)
         for (int j = 0; j < cols; ++j)
            mat[i][j] = initValue;
    }
    
    //
    // Multiplies m1 by m2 if these matrices are conformable.
    // Otherwise, displays an error message and sets m1's size
    // to 0 x 0
    //
    Matrix& Matrix :: operator*=(const Matrix& m2 ) // input
    {
      int val, i, j, k;
      Matrix prod;
       
      if (cols != m2.rows) {
         cout << "Matrices are not conformable." << endl;
         prod.rows = 0;
         prod.cols = 0;
      } else {
         prod.rows = rows;
         prod.cols = m2.cols;
         for (i = 0; i < prod.rows; ++i)
            for (j = 0; j < prod.cols; ++j) {
               val = 0;
               for (k = 0; k < cols; ++k)
                  val += mat[i][k] * m2.mat[k][j];
               prod.mat[i][j] = val;
            }
      }
    
      *this = prod;
      return *this;
    }
    
    //
    // Writes to the output stream the contents of matrix m,
    // one row at a time
    //
    ostream& operator<< ( ostream& os, const Matrix& m )
    {
      for (int i = 0; i < m.rows; ++i) {
         for (int j = 0; j < m.cols; ++j)
            cout << setw( 5 ) << m.mat[i][j];
         cout << endl;
      }
    
      return os;
    }
    
    //
    // Gets the number of rows and columns from the input
    // stream. If rows <= MAX_ROWS and cols <= MAX_COLS,
    // fills m with data from file; otherwise signals failure
    // on stream is. In the event of input failure, sets m size
    // to 0 x 0
    //
    istream& operator>> ( istream& is, Matrix& m )
    {
      int i, j;
    
      is >> m.rows >> m.cols;
      if (is.fail()) {
         m.rows = 0;
         m.cols = 0;
      } else if (m.rows > MAX_ROWS || m.cols > MAX_COLS) {
         is.setstate( ios::failbit);
         m.rows = 0;
         m.cols = 0;
      } else {
         for (i = 0; i < m.rows; ++i)
            for (j = 0; j < m.cols; ++j)
               is >> m.mat[i][j];
         if (is.fail()) {
            m.rows = 0;
            m.cols = 0;
         }
      }
    
      return is;
    }
    I should be able to use the * function defined here in my ^ function. Not much has to be changed...any ideas?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You can use a lot of that code. The * function there is actually *=, which is a little different. Also, your operator^ will have to take an int, not another Matrix.

    Good C++ techinque would be to implement ^= and the copy constructor, and then implement operator^ in terms of the other two. I don't know if you need to go that far for this simple assignment, but it's worth mentioning.

    Again, good luck modifying the code to your needs. Come back with any specific questions you have.

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    15
    I've seprated the int main into it's own cpp file, and it look just like my first post. Now this is what I have for my header file:

    Code:
    #include <string>
    using namespace std;
    
    const int MAX_ROWS = 6;
    const int MAX_COLS = 6;
    
    class Matrix {
    
    public:
    	Matrix() {}
    	Matrix(int = 0, int = 0, int = 0); //constructor that initializes matrix
    							//size and sets all valid elements to ints
    							//given intial value
    	Matrix& operator*=(const Matrix&);
    	Matrix& operator^ (int);
    private:
    	int rows;
    	int cols;
    	double mat[MAX_ROWS][MAX_COLS];
    friend ostream& operator<< (ostream&, const Matrix&);
    friend istream& operator>> (istream&, Matrix&);
    };
    
    //constructor that initializes a Matrix object of size initRows
    //x initCols, setting matrix elements to initValue
    
    Matrix :: Matrix(int initRows, int initCols, double initValue)
    {
    	rows = initRows;
    	cols = initCols;
    	for(int i = 0; i < rows; ++i)
    		for(int j = 0; j < cols; ++j)
    			mat[i][j] = initValue;
    }
    
    //Multiplies m1 by m2 if these matrices are conformable
    //Otherwise, displays an error message and sets m1's size to
    // 0 x 0
    //call this function within ^ function
    //m^n = m.operator^(n)
    Matrix& Matrix :: operator*=(const Matrix& m2) //input
    {
    	int i, j, k;
    	double val;
    	Matrix prod;
    
    	if (cols != m2.rows) {
    		cout << "Matrices are not conformable." << endl;
    		prod.rows = 0;
    		prod.cols = 0;
    	} else {
    		prod.rows = rows;
    		prod.cols = m2.cols;
    		for(i = 0; i < prod.rows; ++i)
    			for (j = 0; j < prod.cols; ++j) {
    				val = 0;
    				for(k = 0; k < cols; ++k)
    					val += mat[i][k] * m2.mat[k][j];
    				prod.mat[i][j] = val;
    			}
    	}
    
    	*this = prod;
    	return = *this;
    
    }
    Matrix& Matrix:: operator ^(int n)
    {
    	int count;
    	Matrix prod = *this;
    
    	for (count = 1; count < n; ++count){
    		*this *= prod;
    	}
    	return *this;
    }
    
    
    
    //writes to the ouput stream the contents of matrix m, one row at a time
    
    ostream& operator<< (ostream& os, const Matrix& m)
    {
    	for(int i = 0; i < m.rows; ++i){
    		for (int j = 0; j < m.cols; ++j)
    			cout << setw(14) << m.mat[i][j];
    		cout << endl;
    	}
    	return os;
    }
    
    istream& operator>> (istream& is, Matrix& m)
    {
    	int i, j;
    
    	is >> m.rows >> m.cols;
    	if (is.fail()){
    		m.rows = 0;
    		m.cols = 0;
    	} else if (m.rows > MAX_ROWS || m.cols > MAX_COLS) {
    		is.setstate(ios::failbit);
    		m.rows = 0;
    		m.cols = 0;
    	} else {
    		for (i = 0; i < m.rows; ++i)
    			for (j = 0; j < m.cols; ++j)
    				is >> m.mat[i][j];
    		if (is.fail()){
    			m.rows = 0;
    			m.cols = 0;
    		}
    	}
    	return is;
    }
    does that look right?

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    15
    I'm getting these errors:

    Code:
    c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(26) : warning C4520: 'Matrix' : multiple default constructors specified
    c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(32) : error C2511: 'Matrix::Matrix(int,int,double)' : overloaded member function not found in 'Matrix'
            c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(11) : see declaration of 'Matrix'
    c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(49) : error C2668: 'Matrix::Matrix' : ambiguous call to overloaded function
            c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(15): could be 'Matrix::Matrix(int,int,int)'
            c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(14): or       'Matrix::Matrix(void)'
            while trying to match the argument list '(void)'
    c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(68) : error C2059: syntax error : '='
    c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.cpp(11) : error C2668: 'Matrix::Matrix' : ambiguous call to overloaded function
            c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(15): could be 'Matrix::Matrix(int,int,int)'
            c:\Documents and Settings\Kevin\My Documents\Visual Studio Projects\HW12\hw12.h(14): or       'Matrix::Matrix(void)'
            while trying to match the argument list '(void)'

  7. #7
    Registered User
    Join Date
    Oct 2005
    Posts
    15
    Nevermind, I got it. Thanks for the tip earlier, Daved.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Zeroing out member arrays in a Structure
    By manofsteel972 in forum C++ Programming
    Replies: 4
    Last Post: 03-26-2004, 03:50 AM
  2. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM